'use strict';

const Service = require('egg').Service;
const utility = require('utility');
const JWT = require('jsonwebtoken');

class UserService extends Service {
    async register(data) { // 注册
        // 开启事务
        const result = await this.app.mysql.beginTransactionScope(async conn => {
            const userList = [];
            const now = Date.now();
            data.password = utility.md5(data.password);
            userList.push({
                nick_name: data.nickName,
                account: data.account,
                password: data.password,
                create_time: now,
                update_time: now
            });
            try {
                // 先校验邀请码是否正确
                const res = await conn.select('invite', {
                    where: {
                        invite_code: data.code
                    }
                });
                if (!res || res.length === 0) {
                    return {
                        message: '该邀请码不存在，请确认后再试',
                        status: 501,
                        result: null
                    };
                }

                // 检查用户名是否重复
                const accountCheck = await conn.query(`select * from user where account='${data.account}'`);
                console.log(accountCheck.rowData);
                if (accountCheck && accountCheck.length > 0) {
                    return {
                        message: '用户名重复，请修改后重试',
                        status: 501,
                        result: null
                    }
                }

                // 检查昵称是否重复
                const nickNameCheck = await conn.query(`select * from user where nick_name='${data.nick_name}'`);
                if (nickNameCheck && nickNameCheck.length > 0) {
                    return {
                        message: '昵称重复，请修改后重试',
                        status: 501,
                        result: null
                    }
                }

                // 写入
                const insertOpe = await conn.insert('user', userList);
                if (insertOpe.affectedRows !== 1) {
                    console.log('写入用户信息出错');
                    return {
                        message: '系统异常',
                        status: 501,
                        result: null
                    }
                }
                console.log(insertOpe, insertOpe.insertId);

                // 更新invite表
                const updateRecord = await conn.query(`update invite set invite_count='${res[0].invite_count + 1}' where user_id='${res[0].user_id}'`);
                if (updateRecord.affectedRows !== 1) {
                    console.log('更新邀请表出错');
                    return {
                        message: '系统异常',
                        status: 501,
                        result: null
                    }
                }

                // 写入邀请关系表
                const insertRelation = await conn.insert('invite_relation', [{
                    user_id: res[0].user_id,
                    be_invited_user_id: insertOpe.insertId
                }]);
                if (insertRelation.affectedRows !== 1) {
                    console.log('写入邀请关系表出错');
                    return {
                        message: '系统异常',
                        status: 501,
                        result: null
                    }
                }

                return {
                    message: '注册成功',
                    status: 200,
                    result: true
                }
            } catch (err) {
                console.log(err);
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        }, this.ctx);
        return result;
    }

    async login(data) {
        // 开启事务
        const result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                // 检查账号是否存在
                const checkAccount = await conn.select('user', {
                    where: {
                        account: data.account
                    }
                });
                let password = '';
                if (checkAccount && checkAccount.length > 0) {
                    password = checkAccount[0].password;
                    let inputPassword = utility.md5(data.password);
                    if (inputPassword === password) {
                        // 签发jwt token
                        const token = JWT.sign({
                            userId: checkAccount[0].id,
                            nickName: checkAccount[0].nick_name,
                            account: checkAccount[0].account,
                            avatar: checkAccount[0].avatar
                        }, this.config.jwt.secret, {
                            expiresIn: this.config.jwt.expiresIn
                        });
                        // 写入缓存
                        await this.ctx.service.cache.set(`profile_${checkAccount[0].id}`, {
                            id: checkAccount[0].id,
                            nickName: checkAccount[0].nick_name,
                            account: checkAccount[0].account,
                            gender: checkAccount[0].gender,
                            birth: checkAccount[0].birth,
                            brief: checkAccount[0].brief,
                            website: checkAccount[0].website,
                            avatar: checkAccount[0].avatar,
                            userEmail: checkAccount[0].email,
                            telephone: checkAccount[0].telephone,
                            total_words: checkAccount[0].total_words,
                            article_count: checkAccount[0].article_count,
                            focus_count: checkAccount[0].focus_count,
                            fans_count: checkAccount[0].fans_count
                        }, 60*60);
                        return {
                            message: '登录成功',
                            status: 200,
                            result: {
                                data: {
                                    id: checkAccount[0].id,
                                    nickName: checkAccount[0].nick_name,
                                    account: checkAccount[0].account,
                                    avatar: checkAccount[0].avatar
                                },
                                token
                            }
                        }
                    } else {
                        return {
                            message: '密码错误，请检查拼写',
                            status: 501,
                            result: null
                        }
                    }
                } else {
                    return {
                        message: '该用户名不存在，请检查拼写或者注册新账号',
                        status: 501,
                        result: null
                    }
                }
            } catch (err) {
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }

    async generateInviteCode(userObj) {
        // 开启事务
        const result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                const code = `ivc_${userObj.userId}${Date.now()}`; // 邀请码就是ivc_ + 用户id + 当前时间戳

                // 先检查invite表中，有没有当前用户的记录
                const checkRecode = await conn.select('invite', {
                    where: {
                        user_id: userObj.userId
                    }
                })

                if (!checkRecode || checkRecode.length === 0) {
                    const addRecord = await conn.insert('invite', [{
                        user_id: userObj.userId,
                        invite_code: code,
                        invite_count: 0,
                        nick_name: userObj.nickName
                    }]);
                    if (addRecord.affectedRows === 1) {
                        return {
                            message: 'ok',
                            status: 200,
                            result: {
                                code
                            }
                        }
                    }
                } else {
                    const updateRecord = await conn.query(`update invite set invite_code='${code}' where user_id='${userObj.userId}'`);
                    if (updateRecord.affectedRows === 1) {
                        return {
                            message: 'ok',
                            status: 200,
                            result: {
                                code
                            }
                        }
                    }
                }
            } catch (err) {
                console.log(err);
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }

    async checkCode(code) {
        // 开启事务
        const result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                const res = await conn.select('invite', {
                    where: {
                        invite_code: code
                    }
                });
                if (res && res.length > 0) {
                    return {
                        message: 'ok',
                        status: 200,
                        result: true
                    };
                } else {
                    return {
                        message: '该邀请码不存在，请确认后再试',
                        status: 501,
                        result: null
                    };
                }
            } catch (err) {
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }

    async profile(id) {
        const userId = id ? id : this.ctx.user.userId;
        const userCache = await this.ctx.service.cache.get(`profile_${userId}`);
        let result = null;
        if (!userCache) {
            // 开启事务
            result = await this.app.mysql.beginTransactionScope(async conn => {
                try {
                    // 查询用户信息
                    const res = await conn.select('user', {
                        where: {
                            id: userId
                        }
                    });
                    if (res && res.length > 0) {
                        const obj = {
                            id: res[0].id,
                            nickName: res[0].nick_name,
                            account: res[0].account,
                            gender: res[0].gender,
                            birth: res[0].birth,
                            brief: res[0].brief,
                            website: res[0].website,
                            avatar: res[0].avatar,
                            userEmail: res[0].email,
                            telephone: res[0].telephone,
                            total_words: res[0].total_words,
                            article_count: res[0].article_count,
                            focus_count: res[0].focus_count,
                            fans_count: res[0].fans_count
                        }
                        await this.ctx.service.cache.set(`profile_${res[0].id}`, obj, 60 * 60);
                        return {
                            message: 'ok',
                            status: 200,
                            result: obj
                        };
                    } else {
                        return {
                            message: '查询的用户不存在',
                            status: 501,
                            result: null
                        };
                    }
                } catch (err) {
                    return {
                        message: '系统异常，请稍后再试',
                        status: 501,
                        result: null
                    };
                }
            });
        } else {
            result = {
                message: '读取缓存',
                status: 200,
                result: userCache
            }
        }
        return result;
    }

    async saveUserInfo(data) {
        // 开启事务
        let result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                const userId = this.ctx.user.userId;
                let str = '';
                let cacheObj = await this.ctx.service.cache.get(`profile_${userId}`);
                for (let key in data) {
                    switch (key) {
                        case 'avatar':
                        case 'telephone':
                        case 'website':
                        case 'brief':
                        case 'gender':
                            str += `${key}='${data[key]}',`;
                            cacheObj[key] = data[key];
                            break;
                        case 'nickName':
                            str += `nick_name='${data[key]}',`;
                            cacheObj[key] = data[key];
                            break;
                        case 'userEmail':
                            str += `email='${data[key]}',`;
                            cacheObj[key] = data[key];
                            break;
                        default:
                    }
                }
                if (str.length > 0) {
                    str = str.substr(0, str.length - 1);
                }
                const updateRecord = await conn.query(`update user set ${str} where id='${userId}'`);
                if (updateRecord.affectedRows === 1) {
                    // 同时更新redis缓存
                    await this.ctx.service.cache.set(`profile_${userId}`, cacheObj, 60 * 60);
                    return {
                        message: '个人信息更新成功',
                        status: 200,
                        result: true
                    }
                } else {
                    return {
                        message: '无数据更新',
                        status: 200,
                        result: true
                    }
                }
            } catch (err) {
                console.log(err)
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }

    async homeInfo(data) { // 获取用户主页的头信息
        // 开启事务
        let result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                const userId = data.id;
                // 从缓存中获取用户信息
                let user = null;
                const cache = await this.ctx.service.user.profile(userId);
                if (cache.status !== 200) {
                    return {
                        message: cache.message,
                        status: cache.status,
                        result: cache.result
                    }
                }
                user = cache.result;
                user.isFocus = false;
                const loginUserId = this.ctx.user.userId;
                if (loginUserId) { // 存在userid，则检查下，是否关注该作者
                    const isFocus = await conn.query(`select id from focus where focus_id=${loginUserId} and be_focus_id=${data.id}`);
                    user.isFocus = !!isFocus.length;
                }
                // 查询收获的点赞
                const like = await conn.query(`select id from like_relative where be_user_id=${userId}`);
                user.be_like_count = like.length;
                return {
                    message: 'ok',
                    status: 200,
                    result: user
                }
            } catch (err) {
                console.log(err)
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }

    async focus(data) { // 关注作者
        // 开启事务
        let result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                const userId = this.ctx.user.userId;
                // 判断是否已经关注过了
                const res = await conn.select('focus', {
                    where: {
                        focus_id: userId,
                        be_focus_id: data.id
                    }
                });
                if (res.length > 0) { // 已经关注过了
                    return {
                        message: 'ok',
                        status: 200,
                        result: true
                    }
                }
                // 在关注表中插入记录
                const insert = await conn.insert('focus', [{
                    focus_id: userId,
                    be_focus_id: data.id
                }]);
                if (insert.affectedRows !== 1) {
                    console.log('写入关注表出错');
                    return {
                        message: '系统异常，请稍后再试',
                        status: 501,
                        result: null
                    }
                }
                // 查询关注者和被关注者的用户信息
                let fUser = null, bfUser = null;
                const cache1 = await this.ctx.service.user.profile(userId);
                if (cache1.status !== 200) {
                    return {
                        message: cache1.message,
                        status: cache1.status,
                        result: cache1.result
                    }
                }
                const cache2 = await this.ctx.service.user.profile(data.id);
                if (cache2.status !== 200) {
                    return {
                        message: cache2.message,
                        status: cache2.status,
                        result: cache2.result
                    }
                }
                fUser = cache1.result;
                bfUser = cache2.result;
                // 更新被关注者的粉丝数
                const update1 = await conn.query(`update user set fans_count=${(bfUser.fans_count || 0) + 1} where id=${data.id}`);
                bfUser.fans_count = (bfUser.fans_count || 0) + 1;
                // 更新关注者的关注数
                const update2 = await conn.query(`update user set focus_count=${(fUser.focus_count || 0) + 1} where id=${userId}`);
                fUser.focus_count = (fUser.focus_count || 0) + 1;
                if (update1.affectedRows !== 1 || update2.affectedRows !== 1) {
                    console.log('user/focus接口，更新用户表时出错');
                    return {
                        message: '系统异常，请稍后再试',
                        status: 501,
                        result: null
                    }
                }
                // 更新缓存
                await this.ctx.service.cache.set(`profile_${userId}`, fUser, 60 * 60);
                await this.ctx.service.cache.set(`profile_${data.id}`, bfUser, 60 * 60);

                return {
                    message: 'ok',
                    status: 200,
                    result: true
                }
            } catch (err) {
                console.log(err)
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }

    async cancelFocus(data) { // 取消关注作者
        // 开启事务
        let result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                const userId = this.ctx.user.userId;
                // 判断是否已经关注过了
                const res = await conn.select('focus', {
                    where: {
                        focus_id: userId,
                        be_focus_id: data.id
                    }
                });
                if (res.length <= 0) { // 还未关注
                    return {
                        message: 'ok',
                        status: 200,
                        result: true
                    }
                }
                // 在关注表中删除记录
                const del = await conn.delete('focus', {
                    focus_id: userId,
                    be_focus_id: data.id
                });
                if (!del) {
                    console.log('删除关注表出错');
                    return {
                        message: '系统异常，请稍后再试',
                        status: 501,
                        result: null
                    }
                }
                // 查询关注者和被关注者的用户信息
                let fUser = null, bfUser = null;
                const cache1 = await this.ctx.service.user.profile(userId);
                if (cache1.status !== 200) {
                    return {
                        message: cache1.message,
                        status: cache1.status,
                        result: cache1.result
                    }
                }
                const cache2 = await this.ctx.service.user.profile(data.id);
                if (cache2.status !== 200) {
                    return {
                        message: cache2.message,
                        status: cache2.status,
                        result: cache2.result
                    }
                }
                fUser = cache1.result;
                bfUser = cache2.result;
                // 更新被关注者的粉丝数
                const update1 = await conn.query(`update user set fans_count=${(bfUser.fans_count || 0) - 1} where id=${data.id}`);
                bfUser.fans_count = (bfUser.fans_count || 0) - 1;
                // 更新关注者的关注数
                const update2 = await conn.query(`update user set focus_count=${(fUser.focus_count || 0) - 1} where id=${userId}`);
                fUser.focus_count = (fUser.focus_count || 0) - 1;
                if (update1.affectedRows !== 1 || update2.affectedRows !== 1) {
                    console.log('user/focus接口，更新用户表时出错');
                    return {
                        message: '系统异常，请稍后再试',
                        status: 501,
                        result: null
                    }
                }
                // 更新缓存
                await this.ctx.service.cache.set(`profile_${userId}`, fUser, 60 * 60);
                await this.ctx.service.cache.set(`profile_${data.id}`, bfUser, 60 * 60);

                return {
                    message: 'ok',
                    status: 200,
                    result: true
                }
            } catch (err) {
                console.log(err)
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }

    async getCommentAndLike() { // 获取所有作者的评论点赞记录
        // 开启事务
        let result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                let cache = await this.ctx.service.cache.get('author_gift') || {};
                if (JSON.stringify(cache) === '{}') {
                    const like = await conn.query('SELECT be_user_id, count(id) FROM `like_relative` group by be_user_id;');
                    console.log('like', like)
                    like.forEach(v => {
                        cache[v.be_user_id] = {
                            likeCount: v['count(id)']
                        }
                    });
                    const comment = await conn.query('SELECT to_user_id, count(id) FROM `comment` group by to_user_id;');
                    comment.forEach(v => {
                        if (cache[v.to_user_id]) {
                            cache[v.to_user_id].commentCount = v['count(id)'];
                        } else {
                            cache[v.to_user_id] = {
                                commentCount: v['count(id)']
                            }
                        }
                    });
                    await this.ctx.service.cache.set('author_gift', cache, 60 * 60);
                    return {
                        message: 'ok',
                        status: 200,
                        result: cache
                    }
                } else {
                    return {
                        message: '读取缓存',
                        status: 200,
                        result: cache
                    }
                }
            } catch (err) {
                console.log(err)
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }
    async recommendAuthor(data) { // 推荐作者列表
        // 开启事务
        let result = await this.app.mysql.beginTransactionScope(async conn => {
            try {
                const userId = this.ctx.user.userId;
                let sql = '', pageSize = 5;
                let arr = [];
                if (userId) { // 用户已登录
                    const currentUser = await conn.select('user', {
                        where: {
                            id: userId
                        }
                    });
                    if (!currentUser || currentUser.length <= 0) {
                        return {
                            message: '当前用户不存在',
                            status: 501,
                            result: null
                        };
                    }
                    pageSize += (currentUser.focus_count || 0);
                }
                sql = `select * from user order by fans_count asc limit 0, ${pageSize}`;
                const list = await conn.query(sql);
                console.log(list)
                // 查询用户的点赞数和评论数
                const author_gift = await this.ctx.service.user.getCommentAndLike();
                console.log(author_gift)
                if (author_gift.status !== 200) {
                    return {
                        message: author_gift.message,
                        status: author_gift.status,
                        result: author_gift.result
                    }
                }
                const cache = author_gift.result;
                if (userId) { // 如果已登录，需要筛选出未关注的前5个作者
                    // 查询关注关系表
                    const focus = await conn.query(`select * from focus where focus_id=${userId}`);
                    list.forEach(v => {
                        if (v.id != userId) {
                            const filter = focus.filter(val => val.be_focus_id == v.id);
                            if (filter.length <= 0) {
                                arr.push(JSON.parse(JSON.stringify(v)));
                            }
                        }
                    });
                } else { // 取前5个即可
                    let i = 0;
                    while (i < 5) {
                        arr.push(JSON.parse(JSON.stringify(list[i])));
                        i++;
                    }
                }

                const res = arr.map(v => ({
                    id: v.id,
                    nick_name: v.nick_name,
                    gender: v.gender,
                    avatar: v.avatar,
                    fans_count: v.fans_count,
                    like_count: cache[v.id] ? (cache[v.id].likeCount || 0) : 0,
                    comment_count: cache[v.id] ? (cache[v.id].commentCount || 0) : 0
                }))

                return {
                    message: 'ok',
                    status: 200,
                    result: res
                }
            } catch (err) {
                console.log(err)
                return {
                    message: '系统异常，请稍后再试',
                    status: 501,
                    result: null
                };
            }
        });
        return result;
    }
}

module.exports = UserService;